﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Utility.Random;

namespace Utility.BehaviourTree
{
	public class DataBoard : IRandomSource
	{
		public float Time { get; private set; } = 0;
		public float DeltaTime { get; private set; } = 0;
		public int Updates { get; private set; } = 0;

		SystemRandom rnd = new SystemRandom ();

		Dictionary<string, object> objDict = new Dictionary<string, object> ();

		Dictionary<string, int> intDict = new Dictionary<string, int> ();
		Dictionary<string, float> floatDict = new Dictionary<string, float> ();
		Dictionary<string, bool> boolDict = new Dictionary<string, bool> ();

		Dictionary<string, Vector3> vec3Dict = new Dictionary<string, Vector3> ();

		public DataBoard ()
		{

		}

		public void UpdateTime (float dt)
		{
			DeltaTime = dt;
			Time += dt;
			Updates++;
		}

		public void Clear ()
		{
			Time = 0;
			DeltaTime = 0;
			Updates = 0;

			objDict.Clear ();
			intDict.Clear ();
			floatDict.Clear ();
			boolDict.Clear ();
			vec3Dict.Clear ();
		}

		#region data
		public IEnumerable<KeyValuePair<string, object>> ObjectKVPairs => objDict;
		public IEnumerable<KeyValuePair<string, int>> IntKVPairs => intDict;
		public IEnumerable<KeyValuePair<string, float>> FloatKVPairs => floatDict;
		public IEnumerable<KeyValuePair<string, bool>> BoolKVPairs => boolDict;
		public IEnumerable<KeyValuePair<string, Vector3>> Vec3KVPairs => vec3Dict;

		public void Remove (string key)
		{
			objDict.Remove (key);
			intDict.Remove (key);
			floatDict.Remove (key);
			boolDict.Remove (key);
			vec3Dict.Remove (key);
		}

		//obj
		public bool TryGet<T> (string key, out T value)
			where T : class
		{
			value = null;
			object obj;
			if (objDict.TryGetValue (key, out obj))
			{
				value = (T)obj;
				return true;
			}
			return false;
		}

		public void Set<T> (string key, T value)
			where T : class
		{
			Remove (key);
			objDict[key] = value;
		}

		//int
		public bool TryGet (string key, out int value)
		{
			return intDict.TryGetValue (key, out value);
		}

		public void Set (string key, int value)
		{
			Remove (key);
			intDict[key] = value;
		}

		//float
		public bool TryGet (string key, out float value)
		{
			return floatDict.TryGetValue (key, out value);
		}

		public void Set (string key, float value)
		{
			Remove (key);
			floatDict[key] = value;
		}

		//bool
		public bool TryGet (string key, out bool value)
		{
			return boolDict.TryGetValue (key, out value);
		}

		public void Set (string key, bool value)
		{
			Remove (key);
			boolDict[key] = value;
		}

		//vector3
		public bool TryGet (string key, out Vector3 value)
		{
			return vec3Dict.TryGetValue (key, out value);
		}

		public void Set (string key, Vector3 value)
		{
			Remove (key);
			vec3Dict[key] = value;
		}


		#endregion
		#region random
		public double Sample ()
		{
			return ((IRandomSource)rnd).Sample ();
		}
		#endregion

	}
}